// ScreenShotsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ScreenShots.h"
#include "ScreenShotsDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// ScreenShotsDlg dialog




ScreenShotsDlg::ScreenShotsDlg(CWnd* pParent /*=NULL*/)
	: CDialog(ScreenShotsDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	CaptureMode = false;

	RectanglePen = CreatePen (PS_SOLID, 3, RGB(256, 0, 0));
	CapturedWindow = NULL;
}

void ScreenShotsDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(ScreenShotsDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()


// ScreenShotsDlg message handlers

BOOL ScreenShotsDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	CaptureMode = false;
	CapturedWindow = NULL;

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void ScreenShotsDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR ScreenShotsDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



//-------------------------------------------------------------------------------------------------------------------------
void ScreenShotsDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
	//invalidate window
	if(CapturedWindow)
	{
		CapturedWindow->InvalidateRect (NULL, TRUE);
		CapturedWindow->UpdateWindow ();
		CapturedWindow->RedrawWindow (NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
	}


	CStatic *pimg = (CStatic*)GetDlgItem(IDC_FINDER);
	pimg->SetBitmap( ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_FINDERBTNU)) );
	ReleaseCapture();
	CDialog::OnLButtonUp(nFlags, point);
	CaptureMode = false;
}


//-------------------------------------------------------------------------------------------------------------------------
void ScreenShotsDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	CRect r;
	GetDlgItem(IDC_FINDER)->GetWindowRect(&r);
	CStatic *pimg = (CStatic*)GetDlgItem(IDC_FINDER);
	this->ClientToScreen(&point);
	if(point.x > r.left && point.x < r.right &&
	   point.y > r.top  && point.y < r.bottom)
	{
		pimg->SetBitmap( ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_FINDERBTND)) );
		SetCursor(::LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR1)));
		this->SetCapture();
		CaptureMode = true;
	}
	

	CDialog::OnLButtonDown(nFlags, point);
}


//-------------------------------------------------------------------------------------------------------------------------
long ScreenShotsDlg::HighlightFoundWindow (HWND hwndFoundWindow)
{
	HDC		hWindowDC = NULL;  // The DC of the found window.
	HGDIOBJ	hPrevPen = NULL;   // Handle of the existing pen in the DC of the found window.
	HGDIOBJ	hPrevBrush = NULL; // Handle of the existing brush in the DC of the found window.
	RECT		rect;              // Rectangle area of the found window.
	long		lRet = 0;

	// Get the screen coordinates of the rectangle of the found window.
	::GetWindowRect (hwndFoundWindow, &rect);

	// Get the window DC of the found window.
	hWindowDC = ::GetWindowDC (hwndFoundWindow);

	if (hWindowDC)
	{
		// Select our created pen into the DC and backup the previous pen.
		hPrevPen = ::SelectObject (hWindowDC, RectanglePen);

		// Select a transparent brush into the DC and backup the previous brush.
		hPrevBrush = ::SelectObject (hWindowDC, GetStockObject(HOLLOW_BRUSH));

		// Draw a rectangle in the DC covering the entire window area of the found window.
		::Rectangle (hWindowDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top);

		// Reinsert the previous pen and brush into the found window's DC.
		::SelectObject (hWindowDC, hPrevPen);

		::SelectObject (hWindowDC, hPrevBrush);

		// Finally release the DC.
		::ReleaseDC (hwndFoundWindow, hWindowDC);
	}

	return lRet;
}


//-------------------------------------------------------------------------------------------------------------------------
void ScreenShotsDlg::OnMouseMove(UINT nFlags, CPoint point)
{
	if(CaptureMode)
	{	
		//invalidate old window
		if(CapturedWindow)
		{
			CapturedWindow->InvalidateRect (NULL, TRUE);
			CapturedWindow->UpdateWindow ();
			CapturedWindow->RedrawWindow (NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
		}


		//get new window
		this->ClientToScreen(&point);
		this->CapturedWindow = WindowFromPoint(point);		 
		//check if it really window
		if(!::IsWindow(CapturedWindow->m_hWnd))
		{
			CapturedWindow = NULL;
			CDialog::OnMouseMove(nFlags, point);
			return;
		}


		CString capt;
		CString cls;

		this->CapturedWindow->GetWindowText(capt);
		GetClassName(CapturedWindow->m_hWnd, cls.GetBuffer(500), 500);
		cls.ReleaseBuffer();

		GetDlgItem(IDC_CAPTION)->SetWindowText(_T("Caption:\t") + capt + _T("\nClassName:\t") + cls);
		HighlightFoundWindow(CapturedWindow->m_hWnd);
	}
	CDialog::OnMouseMove(nFlags, point);
}
